# import geohash
import h3
from abc import ABC, abstractmethod
from ..enums.pp_enum import *
from ..data_structures.attribute_structures import *
from ..data_structures.weight_structures import *


class Map:
    def __init__(self):
        self.map_range = {}  # geojson格式
        self.cells = {}  # 存储Cell对象的哈希表，键为h3_index，值为Cell对象
        self.pyramid_indexes = []  # 存储区域索引的哈希表，键为区域名称，值为区域索引

    def add_cell(self, cell):
        self.cells[cell.index] = cell

class BaseCell(ABC):
    """格网抽象类"""

    def __init__(self, index: str):
        # 格网索引
        self.index = index

        # 几何属性
        self.vertices = []  # 格点坐标数组 [(lat1, lon1), (lat2, lon2), ...]
        self.init_vertices()  # 初始化格点坐标

        self.center = ()
        self.init_center()  # 初始化格心坐标

        # 邻接格网
        self.neighbors = []  # 邻接单元数组 (存储索引)
        self.init_neighbor()  # 初始化cell的邻接cell的索引

        # 属性数组 (存储Attribute对象)
        self.attributes: List[Attribute] = []

        # 权重数组(存储Weight对象)
        self.weights: List[Weight] = []

        # pp中是否拒绝这个cell
        self.rejected = False

    @abstractmethod
    def init_vertices(self):
        """初始化格点坐标"""
        pass

    @abstractmethod
    def init_center(self):
        """初始化格心坐标"""
        pass

    @abstractmethod
    def init_neighbor(self):
        """初始化邻接cell"""
        pass

    def get_attribute(self, target_attribute):
        """获取cell的属性数组中指定的属性类对象"""
        for attribute in self.attributes:
            if isinstance(attribute, target_attribute):
                return attribute
        return None

    def has_attribute(self, target_attribute):
        """判断cell的属性数组中是否有指定的属性类对象"""
        return self.get_attribute(target_attribute) != None

    def get_weight(self, target_weight):
        """获取cell的权重数组中指定的权重类对象"""
        for weight in self.weights:
            if isinstance(weight, target_weight):
                return weight
        return None


class HexCell(BaseCell):
    """六边形cell"""

    def __init__(self, h3_index):
        super().__init__(h3_index)

        # 道路矢量量化拓扑属性
        self.road_type = RoadType.NOWAY.value  # 默认道路类型

        # pp相关
        self.g_increment = 0
        self.g = 0
        self.h = 0
        self.f = 0
        self.father = None

    def init_center(self):
        self.center = h3.h3_to_geo(self.index)

    def init_vertices(self):
        self.vertices = h3.h3_to_geo_boundary(self.index, geo_json=False)

    def init_neighbor(self):
        neighbor_indexes = h3.k_ring(self.index, 3)  # 获取邻接cell的h3索引
        neighbor_indexes.discard(self.index)  # 移除自身索引
        self.neighbors = [index for index in neighbor_indexes]  # 填充邻接cell的索引


class QuadCell(BaseCell):
    """四边形cell"""

    def __init__(self, quad_index):
        super().__init__(quad_index)

        # 道路矢量量化拓扑属性
        self.road_type = RoadType.NOWAY.value  # 默认道路类型

    def init_vertices(self):
        """初始化格点坐标"""
        # bbox = geohash.bbox(self.index)
        # lat_min = bbox['s']
        # lat_max = bbox['n']
        # lon_min = bbox['w']
        # lon_max = bbox['e']

        # self.vertices = [
        #     (lat_min, lon_min),
        #     (lat_min, lon_max),
        #     (lat_max, lon_max),
        #     (lat_max, lon_min)
        # ]
        pass

    def init_center(self):
        """初始化格心坐标"""
        # self.center = geohash.decode(self.index)
        pass

    def init_neighbor(self):
        """初始化邻接cell"""
        # self.neighbors = list(geohash.neighbors(self.index))
